/**
 * Copyright (c) 2013-2016, Jieven. All rights reserved.
 *
 * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
 * To use it on other terms please contact us at 1623736450@qq.com
 */
package com.zmhz.form;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequestWrapper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.eova.aop.AopContext;
import com.eova.aop.MetaObjectIntercept;
import com.eova.common.Easy;
import com.eova.common.utils.xx;
import com.eova.common.utils.io.FileUtil;
import com.eova.core.meta.MetaDataType;
import com.eova.model.MetaField;
import com.eova.model.MetaObject;
import com.eova.service.sm;
import com.eova.template.common.util.TemplateUtil;
import com.eova.widget.WidgetManager;
import com.eova.widget.WidgetUtil;
import com.jfinal.core.Controller;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.LogKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.MultipartRequest;
import com.jfinal.upload.UploadFile;

/**
 * Form组件
 * 
 * @author Jieven
 * 
 */
public class FormController extends Controller {

	final Controller ctrl = this;

	/** 自定义拦截器 **/
	protected MetaObjectIntercept intercept = null;

	/** 异常信息 **/
	private String errorInfo = "";

	/** 当前操作的主对象 **/
	private final Record record = new Record();

	private final String json = null;

	public void add() throws Exception {
		String objectCode = this.getPara(0);
		MetaObject object = sm.meta.getMeta(objectCode);

		// 字段禁用默认对新增无效
		for (MetaField mf : object.getFields()) {
			mf.put("is_disable", false);
		}

		// 构建关联参数值
		Record fixed = WidgetManager.getRef(this);

		// 业务拦截
		intercept = TemplateUtil.initIntercept(object.getBizIntercept());
		if (intercept != null) {
			AopContext ac = new AopContext(ctrl);
			ac.fixed = fixed;
			intercept.addInit(ac);
		}

		setAttr("fixed", fixed.toJson());
		setAttr("object", object);
		render("/eova/widget/form/add.html");
	}
	public void doAdd() throws Exception {

		String objectCode = this.getPara(0);

		final MetaObject object = sm.meta.getMeta(objectCode);

		String json = HttpKit.readData(getRequest());
		System.out.println(json);
		JSONObject job = JSON.parseObject(json);
		//JSONObject user = (JSONObject) job.get("user");
		Record records1 = getRecordsByJsonObject(job, object.getFields(), object.getPk());
		record.setColumns(records1);
		json = job.toJSONString();
		// 获取当前操作数据
		WidgetManager.buildData(this, object, record, object.getPk(), true);
		//从token值查找userid
		String token = job.getString("token");
		if(!xx.isEmpty(token)) {
			String sql = "select id from frontusers where token =?";
			Integer id = Db.use(object.getDs()).queryInt(sql, token);
			record.set("userid", id);
			record.remove("token");
		}

		intercept = TemplateUtil.initIntercept(object.getBizIntercept());
		// 事务(默认为TRANSACTION_READ_COMMITTED)
		boolean flag = Db.use(object.getDs()).tx(new IAtom() {
			@Override
			public boolean run() throws SQLException {
				try {
					AopContext ac = new AopContext(ctrl, record);

					// 新增前置任务
					if (intercept != null) {
						String msg = intercept.addBefore(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
							return false;
						}
					}

					if (!xx.isEmpty(object.getTable())) {
						// add table
						Db.use(object.getDs()).save(object.getTable(), object.getPk(), record);
					} else {
						// update view
						// WidgetManager.operateView(TemplateConfig.ADD, object, record);
						// 视图无法自动操作，请自定义元对象业务拦截完成持久化逻辑！
					}

					// 新增后置任务
					if (intercept != null) {
						String msg = intercept.addAfter(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
							return false;
						}
					}
				} catch (Exception e) {
					errorInfo = "新增异常:" + TemplateUtil.buildException(e);
					return false;
				}
				return true;
			}
		});
		String zmhzpt_user = record.get("zmhzpt_user");
		json = xx.isEmpty(zmhzpt_user) ? json : zmhzpt_user;
		record.remove("zmhzpt_user");
		// AOP提示信息
		if (!flag) {
			json = JsonKit.toJson(new Easy(errorInfo));
			renderJson(json);
			return;
		}

		// 记录新增日志<此处需要重写日志>
		// EovaLog.dao.info(this, EovaLog.ADD, object.getStr("code"));

		// 新增成功之后
		if (intercept != null) {
			try {
				ArrayList<Record> records = new ArrayList<Record>();
				records.add(record);

				AopContext ac = new AopContext(this, records);
				String msg = intercept.addSucceed(ac);
				if (!xx.isEmpty(msg)) {
					errorInfo = msg;
				}
			} catch (Exception e) {
				errorInfo = TemplateUtil.buildException(e);
				json = JsonKit.toJson(new Easy("新增成功,addSucceed拦截执行异常!" + errorInfo));
				renderJson(json);
				return;
			}
		}
		if(null !=errorInfo && !"".equals(errorInfo)) {
			renderJson(errorInfo);
		}else {
			json = JsonKit.toJson(new Easy());
			renderJson(json);
		}
		

	}
	public void doAdd2() throws Exception {
		ctrl.getRequest();
		ctrl.getResponse().getHeaderNames();
		//如有上传文件先保存文件===========
		String fileDir = "/temp";
		fileDir = FileUtil.formatPath(fileDir);
		List<UploadFile> uploadFiles = getFiles(fileDir);//在磁盘上保存文件
		Enumeration enum1=ctrl.getRequest().getHeaderNames(); 
		while (enum1.hasMoreElements()) {
			String s=(String)enum1.nextElement();   
			System.out.println(s);   
			String[] str=ctrl.getRequest().getParameterValues(s); 
			if(!xx.isEmpty(str))
			for (int i=0;i<str.length;i++){   
			System.out.println(str[i]);   
			}   
		}
		String objectCode = this.getPara(0);

		final MetaObject object = sm.meta.getMeta(objectCode);
		
		String json = ((MultipartRequest)getRequest()).getParameter("json");
		JSONObject job = JSON.parseObject(json);
		//JSONObject user = (JSONObject) job.get("user");
		Record records1 = getRecordsByJsonObject(job, object.getFields(), object.getPk());
		record.setColumns(records1);
		
		json = job.toJSONString();
		// 获取当前操作数据
		WidgetManager.buildData(this, object, record, object.getPk(), true);
		
		String imgvalue = record.getStr("img");
		String dir = "/"+object.getTable();
		String uploadpath =  "/www/wwwroot/static/temp";
		
		if(!xx.isEmpty(uploadFiles)) {
			int i = xx.isEmpty(imgvalue)?1:0;
			for (UploadFile uploadFile:uploadFiles) {
				String fileName = uploadFile.getFileName();
				// 获取文件后缀
				String suffix = FileUtil.getFileType(fileName);
				// 创建新的随机文件名
				String fileName2 = System.currentTimeMillis() + suffix;
				//Integer j=null!=imgvalue?1:20;
				//for (int i = 1; i < j; i++) {
					imgvalue = record.getStr("img"+(i==0?"":i));
					
					if(!xx.isEmpty(dir)) {
						dir = FileUtil.formatPath(dir);
						String xx = uploadFile.getUploadPath();
						uploadpath =  xx.substring(0, xx.length()-fileDir.length());
						uploadpath +=dir;
						// 新文件 Path
						String path = /*file.getUploadPath() + File.separator*/ uploadpath+ File.separator+ fileName;
						if (FileUtil.isExists(path)) {
							FileUtil.delete(path);
						}

						FileUtil.rename(uploadFile.getFile().getPath(), path);
						LogKit.info(uploadFile.getFile().getPath() + " -> " + path);
					}
					record.set("img"+(i==0?"":i), fileName2);
					i++;
				//}
			}
		}
		//=======================
		//从token值查找userid
		String token = job.getString("token");
		if(!xx.isEmpty(token)) {
			String sql = "select id from frontusers where token =?";
			Integer id = Db.use(object.getDs()).queryInt(sql, token);
			record.set("userid", id);
			record.remove("token");
		}

		intercept = TemplateUtil.initIntercept(object.getBizIntercept());
		// 事务(默认为TRANSACTION_READ_COMMITTED)
		boolean flag = Db.use(object.getDs()).tx(new IAtom() {
			@Override
			public boolean run() throws SQLException {
				try {
					AopContext ac = new AopContext(ctrl, record);

					// 新增前置任务
					if (intercept != null) {
						String msg = intercept.addBefore(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
							return false;
						}
					}

					if (!xx.isEmpty(object.getTable())) {
						// add table
						Db.use(object.getDs()).save(object.getTable(), object.getPk(), record);
					} else {
						// update view
						// WidgetManager.operateView(TemplateConfig.ADD, object, record);
						// 视图无法自动操作，请自定义元对象业务拦截完成持久化逻辑！
					}

					// 新增后置任务
					if (intercept != null) {
						String msg = intercept.addAfter(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
							return false;
						}
					}
				} catch (Exception e) {
					errorInfo = "新增异常:" + TemplateUtil.buildException(e);
					return false;
				}
				return true;
			}
		});
		String zmhzpt_user = record.get("zmhzpt_user");
		json = xx.isEmpty(zmhzpt_user) ? json : zmhzpt_user;
		record.remove("zmhzpt_user");
		// AOP提示信息
		if (!flag) {
			json = JsonKit.toJson(new Easy(errorInfo));
			renderJson(json);
			return;
		}

		// 记录新增日志<此处需要重写日志>
		// EovaLog.dao.info(this, EovaLog.ADD, object.getStr("code"));

		// 新增成功之后
		if (intercept != null) {
			try {
				ArrayList<Record> records = new ArrayList<Record>();
				records.add(record);

				AopContext ac = new AopContext(this, records);
				String msg = intercept.addSucceed(ac);
				if (!xx.isEmpty(msg)) {
					errorInfo = msg;
				}
			} catch (Exception e) {
				errorInfo = TemplateUtil.buildException(e);
				json = JsonKit.toJson(new Easy("新增成功,addSucceed拦截执行异常!" + errorInfo));
				renderJson(json);
				return;
			}
		}

		json = JsonKit.toJson(new Easy());
		renderJson(json);

	}

	public void update() throws Exception {

		// 获取关联参数
		Record fixed = WidgetManager.getRef(this);

		AopContext ac = new AopContext(ctrl);
		ac.fixed = fixed;

		// 初始化数据
		buildFormData(true, ac);
		// 业务拦截
		intercept = TemplateUtil.initIntercept(ac.object.getBizIntercept());
		if (intercept != null) {
			intercept.updateInit(ac);
		}

		setAttr("fixed", fixed.toJson());

		render("/eova/widget/form/update.html");
	}

	public void doUpdate() throws Exception {

		String objectCode = this.getPara(0);

		final MetaObject object = sm.meta.getMeta(objectCode);

		String json = HttpKit.readData(getRequest());
		JSONObject job = JSON.parseObject(json);
		
		//JSONObject user = (JSONObject) job.get("user");
		Record records1 = getRecordsByJsonObject(job, object.getFields(), object.getPk());
		record.setColumns(records1);
		json = job.toJSONString();
		// 获取当前操作数据
		WidgetManager.buildData(this, object, record, object.getPk(), false);
		//final Object pkName = object.getPk();
		//从token值查找userid
		String token = job.getString("token");
		if(!xx.isEmpty(token)) {
			String sql = "select id from frontusers where token =?";
			Integer id = Db.use(object.getDs()).queryInt(sql, token);
			record.set("userid", id);
			record.remove("token");
			object.set("pk_name", "userid");
		}
		intercept = TemplateUtil.initIntercept(object.getBizIntercept());
		// 事务(默认为TRANSACTION_READ_COMMITTED)
		boolean flag = Db.use(object.getDs()).tx(new IAtom() {
			@Override
			public boolean run() throws SQLException {
				try {
					AopContext ac = new AopContext(ctrl, record);
					ac.object = object;

					// 修改前置任务
					if (intercept != null) {
						String msg = intercept.updateBefore(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
							return false;
						}
					}

					if (!xx.isEmpty(object.getTable())) {
						// update table
						Db.use(object.getDs()).update(object.getTable(), object.getPk(), record);
					} else {
						// update view
						// WidgetManager.operateView(TemplateConfig.UPDATE, object, record);
						// 视图无法自动操作，请自定义元对象业务拦截完成持久化逻辑！
					}

					// 修改后置任务
					if (intercept != null) {
						String msg = intercept.updateAfter(ac);
						if (!xx.isEmpty(msg)) {
							errorInfo = msg;
						}
					}
				} catch (Exception e) {
					errorInfo = "修改异常:" + TemplateUtil.buildException(e);
					return false;
				}
				return true;
			}

		});
		String zmhzpt_user = record.get("zmhzpt_user");
		json = xx.isEmpty(zmhzpt_user) ? json : zmhzpt_user;
		record.remove("zmhzpt_user");
		// AOP提示信息
		if (!flag) {
			json = JsonKit.toJson(new Easy(errorInfo));
			renderJson(json);
			return;
		}

		// 记录新增日志
		// EovaLog.dao.info(this, EovaLog.UPDATE, object.getStr("code") + "[" + pkValue
		// + "]");

		// 修改成功之后
		if (intercept != null) {
			try {
				ArrayList<Record> records = new ArrayList<Record>();
				records.add(record);

				AopContext ac = new AopContext(this, records);
				String msg = intercept.updateSucceed(ac);
				if (!xx.isEmpty(msg)) {
					errorInfo = msg;
				}
			} catch (Exception e) {
				errorInfo = TemplateUtil.buildException(e);
				json = JsonKit.toJson(new Easy("修改成功,updateSucceed拦截执行异常!" + errorInfo));
				renderJson(json);
				return;
			}
		}
		if(null !=errorInfo || !"".equals(errorInfo)) {
			renderJson(errorInfo);
		}else {
			json = JsonKit.toJson(new Easy());
			renderJson(json);
		}
		
	}

	/*
	 * public void detail() { AopContext ac = new AopContext(ctrl);
	 * buildFormData(false, ac); render("/eova/widget/form/detail.html"); }
	 */

	/**
	 * 查看条数据
	 * 
	 * @throws Exception
	 */
	public void detail() throws Exception {
		AopContext ac = new AopContext(ctrl);
		String objectCode = this.getPara(0);
		// 获取主键的值
		Object pkValue = getPara(1);

		MetaObject object = sm.meta.getMeta(objectCode);
		String json = HttpKit.readData(getRequest());
		JSONObject job = JSON.parseObject(json);
		
		String token = null;
		if(!xx.isEmpty(job))
			token =job.getString("token");
		intercept = TemplateUtil.initIntercept(object.getBizIntercept());

		Record record = null;
		
		if (xx.isEmpty(pkValue)&&!xx.isEmpty(token)) {// 当主键为null时，默认按token查询，默认查询的表中有userid字段
			String sql = "select p1.* from " + object.getTable() + " as p1 "
					+ " left join frontusers as p2 on p1.userid = p2.id" 
					+ " where p2.token = ?";
			record = Db.use(object.getDs()).findFirst(sql, token);
		} else {
			// 根据主键获取对象
			record = Db.use(object.getDs()).findById(object.getView(), object.getPk(), pkValue);
		}
		List<Record> res = new ArrayList<Record>();
		res.add(record);
		if(!xx.isEmpty(record)) {
			WidgetUtil.copyValueColumn(res, object.getPk(), object.getFields());
			// 根据表达式将数据中的值翻译成汉字
			com.zmhz.widget.WidgetManager.convertValueByExp(this, object.getFields(), res);
			//去掉隐藏字段
			com.zmhz.widget.WidgetManager.deleteExcessFields(object.getFields(), record);
		}
		// 查询后置任务
		if (intercept != null) {
			ac = new AopContext(ctrl, record);
			intercept.queryAfter(ac);
		}
		// setAttr("record", record);
		ac.object = object;
		ac.record = record;
		if(!xx.isEmpty(record))
			json = JsonKit.toJson(record);
		else
			json = JsonKit.toJson(new Easy("操作失败"));
			
		renderJson(json);

	}

	/**
	 * 构建对象数据
	 */
	private MetaObject buildFormData(boolean isEdit, AopContext ac) {
		String objectCode = this.getPara(0);
		// 获取主键的值
		Object pkValue = getPara(1);

		MetaObject object = sm.meta.getMeta(objectCode);

		// 根据主键获取对象
		Record record = Db.use(object.getDs()).findById(object.getView(), object.getPk(), pkValue);
		
		

		setAttr("record", record);
		setAttr("object", object);

		ac.object = object;
		ac.record = record;

		return object;
	}

	/**
	 * JSONObject转Record
	 * 
	 * @param record
	 * @param pkName
	 * @return
	 */
	private Record getRecordsByJsonObject(JSONObject record, List<MetaField> items, String pkName) {
		List<Record> records = new ArrayList<Record>();

		// JSONObject ob = JSON.parseObject(json, JSONObject.class);

		//JSONObject o = (JSONObject) record.get("record");// JSON.parseArray(json, JSONObject.class);

		// for (JSONObject o : list) {
		Map<String, Object> map = JSON.parseObject(record + "", new TypeReference<Map<String, Object>>() {
		});
		Record re = new Record();
		re.setColumns(map);
		// 将Text翻译成Value,然后删除val字段
		for (MetaField x : items) {
			String en = x.getEn();// 字段名
			if (xx.isEmpty(map.get(en)))
				continue;
			String exp = x.getStr("exp");// 表达式
			Object value = re.get(en);// 值

			if (!xx.isEmpty(exp)) {
				String valField = en + "_val";
				// 获取值列中的值
				if(!xx.isEmpty(re.get(valField))) {
					value = re.get(valField);
					// 获得值之后删除值列防止持久化报错
					re.remove(valField);
				}
			}
			if(null==value&& !xx.isEmpty(x.get("defaulter"))) {
				value = x.get("defaulter");
			}

			re.set(en, MetaDataType.convert(x, value));
		}
		// 删除主键备份值列
		re.remove("pk_val");
		// 删除Orcle分页产生的rownum_
		if (xx.isOracle()) {
			re.remove("rownum_");
		}
		// records.add(re);

		// }

		return re;
	}

	/**
	 * JSONObject转Record
	 * 
	 * @param record
	 * @param pkName
	 * @return
	 */
	private Record getUpdateRecordsByJsonObject(JSONObject record, List<MetaField> items, String pkName) {

		// JSONObject ob = JSON.parseObject(json, JSONObject.class);

		//JSONObject o = (JSONObject) record.get("record");// JSON.parseArray(json, JSONObject.class);

		// for (JSONObject o : list) {
		Map<String, Object> map = JSON.parseObject(record + "", new TypeReference<Map<String, Object>>() {
		});
		Record re = new Record();
		re.setColumns(map);
		// 将Text翻译成Value,然后删除val字段
		for (MetaField x : items) {
			String en = x.getEn();// 字段名
			if (xx.isEmpty(map.get(en)))
				continue;
			String exp = x.getStr("exp");// 表达式
			Object value = re.get(en);// 值

			if (!xx.isEmpty(exp)) {
				String valField = en + "_val";
				// 获取值列中的值
				value = re.get(valField);
				// 获得值之后删除值列防止持久化报错
				re.remove(valField);
			}

			re.set(en, MetaDataType.convert(x, value));
		}
		// 删除主键备份值列
		re.remove("pk_val");
		// 删除Orcle分页产生的rownum_
		if (xx.isOracle()) {
			re.remove("rownum_");
		}
		// records.add(re);

		// }

		return re;
	}

}